package com.sky.criteria;


import java.util.ArrayList;
import java.util.List;

class Person {
    /**
     * 名称
     */
    private String name;
    /**
     * 性别
     */
    private String gender;
    /**
     * 婚姻状况
     */
    private String maritalStatus;

    public Person(String name, String gender, String married) {
        this.name = name;
        this.gender = gender;
        this.maritalStatus = married;


    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getMaritalStatus() {
        return maritalStatus;
    }

    public void setMaritalStatus(String maritalStatus) {
        this.maritalStatus = maritalStatus;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", maritalStatus='" + maritalStatus + '\'' +
                '}';
    }

    /**
     * 初始化用户类
     */
    static List<Person> getPerson() {
        List<Person> persons = new ArrayList<>();
        persons.add(new Person("老八", "男", "单身"));
        persons.add(new Person("老六", "男", "结婚"));
        persons.add(new Person("珍珍", "女", "结婚"));
        persons.add(new Person("爱爱", "女", "单身"));
        persons.add(new Person("老Ⅸ", "男", "单身"));
        persons.add(new Person("老k", "男", "单身"));
        return persons;
    }

}


/**
 * 过滤器，进行筛选
 */
interface Criteria {
    /**
     * 满足符合标准的返回
     *
     * @param persons 集合
     * @return 返回符合标准的集合
     */
    List<Person> meetCriteria(List<Person> persons);
}

/**
 * 筛选出男性
 */
class CriteriaMale implements Criteria {

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> malePersons = new ArrayList< >();
        for (Person person : persons) {
            if (person.getGender().equalsIgnoreCase("男")) {
                malePersons.add(person);
            }
        }
        return malePersons;
    }
}


/**
 * 筛选出女性
 */
class CriteriaFemale implements Criteria {

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> femalePersons = new ArrayList< >();
        for (Person person : persons) {
            if (person.getGender().equalsIgnoreCase("女")) {
                femalePersons.add(person);
            }
        }
        return femalePersons;
    }
}


/**
 * 过滤单身
 */
class CriteriaSingle implements Criteria {

    @Override
    public List<Person> meetCriteria(List<Person> persons) {


        List<Person> singlePersons = new ArrayList<>();


        for (Person person : persons) {
            if (person.getMaritalStatus().equalsIgnoreCase("单身")) {
                singlePersons.add(person);
            }
        }
        return singlePersons;
    }
}


/**
 * 两种条件的交集
 */
class AndCriteria implements Criteria {

    private Criteria criteria;
    private Criteria otherCriteria;

    /**
     * 两种类型进行组合筛选，交集
     *
     * @param criteria      筛选条件
     * @param otherCriteria 额外条件
     */
    AndCriteria(Criteria criteria, Criteria otherCriteria) {
        this.criteria = criteria;
        this.otherCriteria = otherCriteria;
    }

    /**
     * 两种条件进行组合赛选
     *
     * @param persons 集合
     * @return 返回符合两种条件的集合
     */
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);
        return otherCriteria.meetCriteria(firstCriteriaPersons);
    }
}


/**
 * 两种条件的合集
 */
class OrCriteria implements Criteria {

    private Criteria criteria;
    private Criteria otherCriteria;

    /**
     * 两种条件的合集
     *
     * @param criteria      筛选集合
     * @param otherCriteria 筛选集合
     */
    public OrCriteria(Criteria criteria, Criteria otherCriteria) {
        this.criteria = criteria;
        this.otherCriteria = otherCriteria;
    }

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> firstCriteriaItems = criteria.meetCriteria(persons);
        List<Person> otherCriteriaItems = otherCriteria.meetCriteria(persons);

        for (Person person : otherCriteriaItems) {
            if (!firstCriteriaItems.contains(person)) {
                firstCriteriaItems.add(person);
            }
        }
        return firstCriteriaItems;
    }
}


/**
 * date : 2024-09-13
 * 过滤器模式，也称为  Criteria  模式，用于根据多种条件过滤对象。
 * 例如 现实中 许多婚恋网站的爆火 ,  需要 我们筛选 各种婚恋状态的 男男女女 ;
 * 通过实现不同的筛选条件接口，如筛选性别和婚姻状况，可以组合条件进行交集和并集操作。
 *
 * @author : wushikai
 */
public class PureLoveCriteriaApplication {


    public static void main(String[] args) {
        List<Person> persons = Person.getPerson();
        Criteria male = new CriteriaMale();          //男性
        Criteria single = new CriteriaSingle();         //单身
        CriteriaFemale criteriaFemale = new CriteriaFemale();          //女性
        AndCriteria andCriteria = new AndCriteria(single, male);          //交集  单身男性
        OrCriteria orCriteria = new OrCriteria(single, male);         //并集  单身或者男性

        System.out.println("女性: " + criteriaFemale.meetCriteria(persons));
        System.out.println("单身: " + single.meetCriteria(persons));
        System.out.println("单身男性: " + andCriteria.meetCriteria(persons));
        System.out.println("单身或是男性: " + orCriteria.meetCriteria(persons));
    }


}
